package edu.polsl.bio.str.manager.messaging;

import edu.polsl.bio.str.manager.command.Command;
import edu.polsl.bio.str.manager.event.*;
import edu.polsl.bio.str.manager.logic.JobDispatcherBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.integration.core.Message;
import org.springframework.integration.message.MessageDeliveryException;
import org.springframework.integration.message.MessageHandler;
import org.springframework.integration.message.MessageHandlingException;
import org.springframework.integration.message.MessageRejectedException;

/**
 * //todo class description
 * <p/>
 * Created on: Jun 14, 2011 1:40:06 PM <br/>
 * <a href="http://www.polsl.pl">www.polsl.pl</a>
 *
 * @author lukasz.olczak@polsl.pl
 */
public class ManagerEventHandler implements MessageHandler, ManagerHandlerVisitor, ApplicationContextAware {
  /**
   * slf4j Logger.
   */
  private static final Logger log = LoggerFactory.getLogger(ManagerEventHandler.class.getName());

  private JobDispatcherBean jobDispatcherBean;

  private ManagerMessagePublisher messagePublisher;

  private ApplicationContext applicationContext;

  @Override
  public void handleMessage(Message<?> message) throws MessageRejectedException, MessageHandlingException, MessageDeliveryException {
    try {
      BaseManagerEvent bmEvent = (BaseManagerEvent) message.getPayload();
      log.debug("Handling {}", bmEvent);
      bmEvent.visit(this);
    } catch (Exception e) {
      log.error("Exception occurred during event handling", e);
    }
  }

  @Override
  public void onNewJobGroupEvent(NewJobGroupEvent event) {
    log.debug("Handling new job group event");
    try {
      jobDispatcherBean.dispatchWaitingJobs();
    } catch (Exception e) {
      log.error("Exception occurred during dispatching jobs", e);
    }
  }


  @Override
  public void onNewNodeAttachedEvent(NewNodeAttachedEvent event) {
    try {
      jobDispatcherBean.dispatchWaitingJobs();
    } catch (Exception e) {
      log.error("Exception occurred during dispatching jobs", e);
    }
  }

  @Override
  public void onDotPlotResultsEvent(DotPlotResultsEvent event) {
    log.debug("Handling dot plot results event");

    try {
      jobDispatcherBean.persistJobEnd(event.getJobId(), event.getNodeId());
      jobDispatcherBean.dispatchWaitingJobs();
    } catch (Exception e) {
      log.error("Exception occurred during results persisting", e);
    }
    Command cmd = (Command) applicationContext.getBean("dotPlotLoaderCmd");
    cmd.setContext(event.getResults());
    messagePublisher.publishLoaderCommand(cmd);
  }

  public void setJobDispatcherBean(JobDispatcherBean jobDispatcherBean) {
    this.jobDispatcherBean = jobDispatcherBean;
  }

  public void setMessagePublisher(ManagerMessagePublisher messagePublisher) {
    this.messagePublisher = messagePublisher;
  }

  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    this.applicationContext = applicationContext;
  }
}
